using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.ProcessManagement;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ProcessManagements;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ProcessManagements
{
    /// <summary>
    /// 新增工序 处理器
    /// </summary>
    public class AddProcessHandler : IRequestHandler<AddProcessCommand, APIResult<int>>
    {
        private readonly IBaseRepository<ProcessInfo> _processRepo;
        private readonly IBaseRepository<ProcessAttachment> _attachRepo;
        private readonly ILogger<AddProcessHandler> _logger;

        public AddProcessHandler(
            IBaseRepository<ProcessInfo> processRepo,
            IBaseRepository<ProcessAttachment> attachRepo,
            ILogger<AddProcessHandler> logger)
        {
            _processRepo = processRepo;
            _attachRepo = attachRepo;
            _logger = logger;
        }

        public Task<APIResult<int>> Handle(AddProcessCommand request, CancellationToken cancellationToken)
        {
            var res = new APIResult<int>();
            try
            {
                // 基础校验
                if (string.IsNullOrWhiteSpace(request.ProcessCode))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序编码不能为空";
                    return Task.FromResult(res);
                }
                if (string.IsNullOrWhiteSpace(request.ProcessName))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序名称不能为空";
                    return Task.FromResult(res);
                }
                if (request.Status != 0 && request.Status != 1)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "状态只能是0(禁用)或1(启用)";
                    return Task.FromResult(res);
                }

                // 唯一性校验
                var dupCode = _processRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessInfo WHERE ProcessCode = @ProcessCode AND IsDeleted = 0",
                    new { request.ProcessCode });
                if (dupCode > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序编码已存在";
                    return Task.FromResult(res);
                }
                var dupName = _processRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessInfo WHERE ProcessName = @ProcessName AND IsDeleted = 0",
                    new { request.ProcessName });
                if (dupName > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序名称已存在";
                    return Task.FromResult(res);
                }

                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);

                // 插入主表，返回新Id
                var insertSql = @"INSERT INTO ProcessInfo 
                                    (ProcessCode, SystemCode, ProcessName, ClassificationId, ClassificationName, DepartmentId, DepartmentName, OwnerUserId, OwnerUserName, Status, Remark, CreateTime, CreateUser, IsDeleted)
                                  VALUES
                                    (@ProcessCode, @SystemCode, @ProcessName, @ClassificationId, @ClassificationName, @DepartmentId, @DepartmentName, @OwnerUserId, @OwnerUserName, @Status, @Remark, @CreateTime, @CreateUser, @IsDeleted);
                                  SELECT LAST_INSERT_ID();";

                var now = DateTime.Now;
                var newId = _processRepo.QueryFirstOrDefault<int>(insertSql, new
                {
                    request.ProcessCode,
                    request.SystemCode,
                    request.ProcessName,
                    request.ClassificationId,
                    request.ClassificationName,
                    request.DepartmentId,
                    request.DepartmentName,
                    request.OwnerUserId,
                    request.OwnerUserName,
                    request.Status,
                    request.Remark,
                    CreateTime = now,
                    CreateUser = "system",
                    IsDeleted = false
                });

                if (newId <= 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "新增失败";
                    return Task.FromResult(res);
                }

                // 附件（可选）
                if (request.Attachments != null && request.Attachments.Count > 0)
                {
                    var attachSql = @"INSERT INTO ProcessAttachment
                                        (ProcessId, FileName, FileUrl, FileSize, ContentType, FileHash, UploadTime, UploaderId, UploaderName, Status, Remark, CreateTime, CreateUser, IsDeleted)
                                      VALUES
                                        (@ProcessId, @FileName, @FileUrl, @FileSize, @ContentType, @FileHash, @UploadTime, @UploaderId, @UploaderName, @Status, @Remark, @CreateTime, @CreateUser, @IsDeleted);";

                    foreach (var a in request.Attachments)
                    {
                        _attachRepo.Execute(attachSql, new
                        {
                            ProcessId = (long)newId,
                            a.FileName,
                            a.FileUrl,
                            a.FileSize,
                            a.ContentType,
                            a.FileHash,
                            UploadTime = now,
                            UploaderId = (long?)null,
                            UploaderName = (string?)null,
                            a.Status,
                            a.Remark,
                            CreateTime = now,
                            CreateUser = "system",
                            IsDeleted = false
                        });
                    }
                }

                scope.Complete();

                res.Code = APIEnums.Success;
                res.Data = newId;
                res.Msg = "新增成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增工序失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "新增工序异常";
                res.Data = 0;
            }

            return Task.FromResult(res);
        }
    }
}
